#include <string>
#include "RecursoDeAlmacenamiento.h"


void EstrategiaRecursoEscrituraDirecta::crear(RecursoDeAlmacenamiento* recurso, enumAlmacenamiento estAlmacenamiento, enumIndice estIndice, int longitudBuffer, int longitudBloqueIndice, int longitudBloque){
	//creacion del buffer de lectura

	Buffer newBuffer(longitudBuffer);
	recurso->setBuffer(&newBuffer);

	//creacion del archivo
	if(estAlmacenamiento == TEXTO){
			cout << "Creando AlmacenamientoTexto" << endl;
			EstrategiaAlmacenamientoTexto* a = new EstrategiaAlmacenamientoTexto();
			Archivo newFile(recurso->getNombreArchivo(), a, longitudBloque);
			recurso->setArchivo(&newFile);
			this->crearIndice(recurso, a, estIndice, longitudBloqueIndice, longitudBloque);
	} else if(estAlmacenamiento == REGISTROS){
			cout << "Creando AlmacenamientoRegistros" << endl;
			EstrategiaAlmacenamientoRegistros* a = new EstrategiaAlmacenamientoRegistros();
			Archivo newFile(recurso->getNombreArchivo(), a, longitudBloque);
			recurso->setArchivo(&newFile);
			this->crearIndice(recurso, a, estIndice, longitudBloqueIndice, longitudBloque);
	} else if(estAlmacenamiento == BLOQUES){
			cout << "Creando AlmacenamientoBloques" << endl;
			EstrategiaAlmacenamientoBloques* a = new EstrategiaAlmacenamientoBloques();
			Archivo newFile(recurso->getNombreArchivo(), a, longitudBloque);
			recurso->setArchivo(&newFile);
			this->crearIndice(recurso, a, estIndice, longitudBloqueIndice, longitudBloque);
	} else {
			EstrategiaAlmacenamientoRegistros* a = new EstrategiaAlmacenamientoRegistros();
			Archivo newFile(recurso->getNombreArchivo(), a, longitudBloque);
			recurso->setArchivo(&newFile);
			this->crearIndice(recurso, a, estIndice, longitudBloqueIndice, longitudBloque);
	}
}

void EstrategiaRecursoEscrituraDirecta::crearIndice(RecursoDeAlmacenamiento* recurso, EstrategiaAlmacenamiento* eAlmacenamiento, enumIndice estIndice, int longitudBloqueIndice, int longitudBloque){
	if(estIndice == HASH_EXTENSIBLE){
			IndexadoHashExtensible* i = new IndexadoHashExtensible();
			Indice newIndex(recurso->getNombreArchivo(), i, eAlmacenamiento, longitudBloque, longitudBloqueIndice);
			recurso->setIndice(&newIndex);
	} else if(estIndice == BSHARP){
			IndexadoBSharp* i = new IndexadoBSharp();
			Indice newIndex(recurso->getNombreArchivo(), i, eAlmacenamiento, longitudBloque, longitudBloqueIndice);
			recurso->setIndice(&newIndex);
	} else if(estIndice == NO_INDEXADO){
			NoIndexado* i = new NoIndexado();
			Indice newIndex(recurso->getNombreArchivo(), i, eAlmacenamiento, longitudBloque, longitudBloqueIndice);
			recurso->setIndice(&newIndex);
	} else {
			NoIndexado* i = new NoIndexado();
			Indice newIndex(recurso->getNombreArchivo(), i, eAlmacenamiento, longitudBloque, longitudBloqueIndice);
			recurso->setIndice(&newIndex);
	}
}

void EstrategiaRecursoEscrituraDirecta::almacenar(RecursoDeAlmacenamiento* recurso, Registro registro){
	cout << "Llego al almacenar de la estrategia de recurso" << endl;
	recurso->getBuffer()->almacenar(registro);
	cout << "Almaceno en el buffer" << endl;
	int direccion = recurso->getArchivo()->almacenar(registro);
	cout << "Almaceno en el archivo" << endl;
	recurso->getIndice()->indexar(registro.getValoresClaves(), direccion);
}

void EstrategiaRecursoEscrituraDirecta::cerrar(RecursoDeAlmacenamiento* recurso){
	recurso->getArchivo()->cerrar();
	recurso->getBuffer()->cerrar();
}


void EstrategiaRecursoEscrituraDirecta::modificar(RecursoDeAlmacenamiento* recurso, Registro registro, int offset){
	recurso->getArchivo()->modificar(registro, offset);
	recurso->getBuffer()->modificar(registro, offset);
}

Registro EstrategiaRecursoEscrituraDirecta::buscar(RecursoDeAlmacenamiento* recurso, int offset, list<string> claves){
	Registro r;
	try{
		//busca en el buffer. Si no lo encuentra, busca en el archivo.
		r = recurso->getArchivo()->recuperar(offset, claves);
	} catch(int){
		return recurso->getArchivo()->recuperar(offset, claves);
	}
	return r;
}

void EstrategiaRecursoEscrituraDirecta::borrar(RecursoDeAlmacenamiento* recurso, int offset, list<string> claves){
	recurso->getArchivo()->borrar(offset, claves);
	recurso->getBuffer()->borrar(offset, claves);
}
